
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.tiled.TiledObject;
import com.badlogic.gdx.graphics.g2d.tiled.TiledObjectGroup;

import com.obscure.delib.deAnimationObject;
import com.obscure.delib.deSprite;
import com.tilemap.*;


//from test
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;

interface GUI_gp
{
	public final static int backbutton = 1000;	
	public final static int button1    = 1001;
	public final static int leftbutton = 1002;
	public final static int rightbutton= 1003;
	public final static int jumpbutton = 1004;
}
public class ScreenStateGameplay implements ScreenState {

    private boolean m_isStateDone=false;
    public static TiledMapHelper tiledMapHelper;
	private int screenWidth;
	private int screenHeight; 
	private int lastTouchedX;
	private int lastTouchedY;
	
	private float lastPosX_sprite;
	private float lastPosY_sprite;
	
	private SpriteBatch m_spriteBatch;
    private deSprite m_splashDeSprite;
    private deAnimationObject m_animation;
    private GuiElement m_gbackbutton;
    private GuiElement m_gleftbutton;
    private GuiElement m_gjumpbutton;
    private GuiElement m_grightbutton;
	public int m_NextState=0;
		
	//from gtest
	private Texture overallTexture;
	private World world;
	private Body jumper;
	public static final float PIXELS_PER_METER =60.0f;
	private SpriteBatch spriteBatch;
	private Sprite jumperSprite;
	private boolean jumperFacingRight;
	private Box2DDebugRenderer debugRenderer;
	private deSprite m_button;
	
	static final float BOX_STEP=1/30f;
	static final int  BOX_VELOCITY_ITERATIONS=8;
	static final int BOX_POSITION_ITERATIONS =3;
	float accumulator;
	protected OrthographicCamera camera;
	
	public ScreenStateGameplay(Application app, int nextstate) {
		// TODO Auto-generated constructor stub
		m_NextState =GameState.STATE_MM;
		
		//if (screenWidth == -1) 
		{
			screenWidth = Gdx.graphics.getWidth();
			screenHeight = Gdx.graphics.getHeight();
		}
		world = new World(new Vector2(0.0f, -10.0f), true);
		tiledMapHelper = new TiledMapHelper(world,PIXELS_PER_METER);
		String levelLoaded = "tilemaps/level0" + nextstate;
		String tmxLoaded   = levelLoaded+"/level0" + nextstate+".tmx";
		tiledMapHelper.setPackerDirectory(levelLoaded);
		tiledMapHelper.loadMap(tmxLoaded);
		tiledMapHelper.prepareCamera(screenWidth,screenHeight);
		tiledMapHelper.loadCollisonObject();
		
		m_spriteBatch    = new SpriteBatch();
		spriteBatch = new SpriteBatch();
		m_splashDeSprite = new deSprite();
		m_splashDeSprite.setSptiteBatch(spriteBatch);
		m_splashDeSprite.loadData(DATA_SPRITE.SPR_BUSTER);
		
		m_button = new deSprite();
		m_button.setSptiteBatch(m_spriteBatch);
		m_button.loadData(DATA_SPRITE.SPR_BUTTON);
		
		// back button
		m_gbackbutton = new GuiElement(m_button);
		m_gbackbutton.setPos(730, 480);
		m_gbackbutton.setAnim(SPRITE_BUTTON.ANIM_6);
		m_gbackbutton.setGUIWidthHight(70,52);
		m_gbackbutton.setGuiID(GUI_gp.backbutton);
		GuiElementManager.getInstance().addElement(m_gbackbutton);
		
		// left button
		m_gleftbutton = new GuiElement(m_button);
		m_gleftbutton.setPos(29, 114);
		m_gleftbutton.setAnim(SPRITE_BUTTON.ANIM_7);
		m_gleftbutton.setGUIWidthHight(51,82);
		m_gleftbutton.setGuiID(GUI_gp.leftbutton);
		GuiElementManager.getInstance().addElement(m_gleftbutton);		
		// right button
		m_grightbutton = new GuiElement(m_button);
		m_grightbutton.setPos(134, 114);
		m_grightbutton.setAnim(SPRITE_BUTTON.ANIM_9);
		m_grightbutton.setGUIWidthHight(51,82);
		m_grightbutton.setGuiID(GUI_gp.rightbutton);
		GuiElementManager.getInstance().addElement(m_grightbutton);		
		// jump button
		m_gjumpbutton = new GuiElement(m_button);
		m_gjumpbutton.setPos(65, 114);
		m_gjumpbutton.setAnim(SPRITE_BUTTON.ANIM_8);
		m_gjumpbutton.setGUIWidthHight(84,84);
		m_gjumpbutton.setGuiID(GUI_gp.jumpbutton);
		GuiElementManager.getInstance().addElement(m_gjumpbutton);
		
		m_animation = new deAnimationObject(m_splashDeSprite,0,0);
		m_animation.setPosX(0);
		m_animation.setPosY(10);
		m_animation.setPaintFrameWhenAnimFinish(false);
		m_animation.setAnimLoop(-1);
		m_animation.setAnimIndex(SPRITE_BUSTER.BUSTER_WALK_RIGHT_2);

        // for test
		overallTexture = new Texture(Gdx.files.internal("tilemaps/bg.png"));
		overallTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);

		jumperSprite = new Sprite(overallTexture, 0, 0, 21, 37);
		jumperSprite.setPosition(480.0f, 180.0f);
		m_animation.setPosX(480);
		m_animation.setPosY(180);

		BodyDef jumperBodyDef = new BodyDef();
		jumperBodyDef.type = BodyDef.BodyType.DynamicBody;
		jumperBodyDef.position.set(2.0f, 3.0f);
		lastPosX_sprite =2.0f * PIXELS_PER_METER;
		lastPosY_sprite =3.0f * PIXELS_PER_METER;
		jumper = world.createBody(jumperBodyDef);
		
		PolygonShape jumperShape = new PolygonShape();
		jumperShape.setAsBox(jumperSprite.getWidth() / (2 * PIXELS_PER_METER),
				jumperSprite.getHeight() / (2 * PIXELS_PER_METER));
		
		jumper.setFixedRotation(true);
		
		FixtureDef jumperFixtureDef = new FixtureDef();
		jumperFixtureDef.shape = jumperShape;
		jumperFixtureDef.density = 1.0f;
		jumperFixtureDef.friction = 9.0f;

		jumper.createFixture(jumperFixtureDef);
		jumperShape.dispose();
		
		//tiledMapHelper.loadCollisions("data/collisions.txt", world,
		//		PIXELS_PER_METER);
		
		//camera = new OrthographicCamera((int)(screenWidth/PIXELS_PER_METER), (int)(screenHeight/PIXELS_PER_METER));
		//camera.position.set(-200, 0, 0);
		debugRenderer = new Box2DDebugRenderer();
	}

	@Override
	public void update(Application app) 
	{
		/**
		 * Ensure that the camera is only showing the map, nothing outside.
		 */

		if (tiledMapHelper.getCamera().position.x < screenWidth / 2) 
		{
			tiledMapHelper.getCamera().position.x = screenWidth / 2;
		}
		if (tiledMapHelper.getCamera().position.x >= tiledMapHelper.getWidth() - screenWidth / 2) 
		{
			tiledMapHelper.getCamera().position.x = tiledMapHelper.getWidth()
					- screenWidth / 2;
		}

		if (tiledMapHelper.getCamera().position.y < screenHeight / 2) {
			tiledMapHelper.getCamera().position.y = screenHeight / 2;
		}
		if (tiledMapHelper.getCamera().position.y >= tiledMapHelper.getHeight()
				- screenHeight / 2) {
			tiledMapHelper.getCamera().position.y = tiledMapHelper.getHeight()
					- screenHeight / 2;
		}

		tiledMapHelper.getCamera().update();

		boolean moveLeft = false;
		boolean moveRight = false;
		boolean doJump = false;

		if (Gdx.input.isKeyPressed(Input.Keys.DPAD_RIGHT)) 
		{
			moveRight = true;
		} else 
		{
			for (int i = 0; i < 2; i++) 
			{
				if (Gdx.input.isTouched(i) && Gdx.input.getX() > Gdx.graphics.getWidth() * 0.80f) 
				{
					moveRight = true;
				}
			}
		}

		if (Gdx.input.isKeyPressed(Input.Keys.DPAD_LEFT)) 
		{
			moveLeft = true;
		} else 
		{
			for (int i = 0; i < 2; i++) {
				if (Gdx.input.isTouched(i)
						&& Gdx.input.getX() < Gdx.graphics.getWidth() * 0.20f) {
					moveLeft = true;
				}
			}
		}
		if (Gdx.input.isKeyPressed(Input.Keys.DPAD_UP)) 
		{
			doJump = true;
		} 
		else 
		{
			for (int i = 0; i < 2; i++) 
			{
				if (Gdx.input.isTouched(i)
						&& Gdx.input.getY() < Gdx.graphics.getHeight() * 0.20f) {
					doJump = true;
				}
			}
		}
		
		if (moveRight) 
		{
			jumper.applyLinearImpulse(new Vector2(0.04f, 0.0f),
					jumper.getWorldCenter());
			if (jumperFacingRight == false) {
				jumperSprite.flip(true, false);
			}
			jumperFacingRight = true;
		} else if (moveLeft) 
		{
			jumper.applyLinearImpulse(new Vector2(-0.04f, 0.0f),
					jumper.getWorldCenter());
			if (jumperFacingRight == true) {
				jumperSprite.flip(true, false);
			}
			jumperFacingRight = false;
		}

		if (doJump && Math.abs(jumper.getLinearVelocity().y) < 1e-9) 
		{
			jumper.applyLinearImpulse(new Vector2(0.0f, 0.7f),jumper.getWorldCenter());
		}

    	world.step(1/80.0f, 8, 3);
    	
    	if (Gdx.input.justTouched())
    	{
			lastTouchedX = Gdx.input.getX();
			lastTouchedY = Gdx.input.getY();
		} 
    	else if (Gdx.input.isTouched()) 
		{
			tiledMapHelper.getCamera().position.x += lastTouchedX - Gdx.input.getX();
			tiledMapHelper.getCamera().position.y += Gdx.input.getY() - lastTouchedY;

			lastTouchedX = Gdx.input.getX();
			lastTouchedY = Gdx.input.getY();
		}

    	Vector2 vv = jumper.getPosition();
    		
		float deltaX =(vv.x * PIXELS_PER_METER)-lastPosX_sprite;
		float deltaY =(vv.y * PIXELS_PER_METER)-lastPosY_sprite;
		tiledMapHelper.getCamera().position.x+=deltaX;
		tiledMapHelper.getCamera().position.y+=deltaY;
		lastPosX_sprite=vv.x* PIXELS_PER_METER;
		lastPosY_sprite=vv.y* PIXELS_PER_METER;
   	
		Vector3 tmp = new Vector3();
		tmp.set(0, 0, 0);
    	tiledMapHelper.getCamera().unproject(tmp);
		jumperSprite.setPosition(
				PIXELS_PER_METER * jumper.getPosition().x
						- jumperSprite.getWidth() / 2,
				PIXELS_PER_METER * jumper.getPosition().y
						- jumperSprite.getHeight() / 2);
		
		m_animation.setPosX((int)(PIXELS_PER_METER * jumper.getPosition().x
				- jumperSprite.getWidth() / 2));
		m_animation.setPosY((int)(PIXELS_PER_METER * jumper.getPosition().y
				- jumperSprite.getHeight() / 2));
		
		int clickedGUI = GuiElementManager.getInstance().update(Gdx.input);
		if(clickedGUI != -1) 
		{
			executeClickedButton(clickedGUI);
		}	
	}
	private void executeClickedButton(int clickedGUI) {
		if(clickedGUI == GUI_gp.backbutton)
		{
				System.out.println("--button1 clicked-- ");
				m_NextState =GameState.STATE_MAP;
				m_isStateDone=true;
		}
	}
	@Override
	public void render(Application app) {
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);   //clear screen
        Gdx.gl.glClearColor(255, 2, 255, 255);    //fill screen with white color
        m_spriteBatch.begin();
        m_spriteBatch.draw(overallTexture, 0, 0);
        m_spriteBatch.end();
        spriteBatch.setProjectionMatrix(tiledMapHelper.getCamera().combined);

        tiledMapHelper.render();
        m_animation.render();
        
		/**
		 * "Flush" the sprites to screen.
		 */

		/*
		 debugRenderer.render(world, tiledMapHelper.getCamera().combined.scale(
				PIXELS_PER_METER,
				PIXELS_PER_METER,
				PIXELS_PER_METER));
				*/			
        GuiElementManager.getInstance().render();	
	}

	@Override
	public boolean isDone() {
		return m_isStateDone;
	}

	@Override
	public void dispose() {
		tiledMapHelper.dispose();
		GuiElementManager.getInstance().removeElement(m_gbackbutton);
		GuiElementManager.getInstance().removeElement(m_gleftbutton);
		GuiElementManager.getInstance().removeElement(m_grightbutton);
		GuiElementManager.getInstance().removeElement(m_gjumpbutton);
		m_spriteBatch.dispose();
		m_splashDeSprite.dispose();	
	}

	@Override
	public int getNextState() {
		return m_NextState;
	}

}
